package com.healthcloud.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.healthcloud.dao.MobileCodeMapper;
import com.healthcloud.entity.MobileCode;
import com.healthcloud.exception.BusinessException;
import com.healthcloud.service.MobileCodeService;
import com.healthcloud.utils.EntityUtils;

/**
 * Created by xiam on 2015/6/26.
 */
@Service
@Transactional
public class MobileCodeServiceImpl implements MobileCodeService {

	public static final int MAX_ERROR_TIMES = 5; // 最大尝试次数为5次

	@Autowired
	private MobileCodeMapper mobileCodeMapper;

	@Transactional
	@Override
	public String generateMobileCode(String mobile, Integer useType) {
		String code = RandomStringUtils.randomNumeric(6);
		MobileCode mobileCode = new MobileCode();
		Date now = new Date();
		EntityUtils.setDateTime(now, mobileCode);
        mobileCode.setUsed(Boolean.FALSE);
        mobileCode.setExpiredTime(new Date(System.currentTimeMillis() + 30*60*1000 )); // 有效期30分钟
        mobileCode.setUseType(useType);
        mobileCode.setErrorTimes(0);
        mobileCode.setCode(code);
        mobileCode.setMobile(mobile);
        mobileCodeMapper.save(mobileCode);
		return code;
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	@Override
	public void validate(String mobile, String code, Integer useType) throws BusinessException {
		List<MobileCode> codes = mobileCodeMapper.findByMobieAndUseType(mobile, useType);
		if (CollectionUtils.isEmpty(codes)) {
			throw new BusinessException("error_mobile_code");
		}
		MobileCode mobileCode = codes.get(0);
		if (mobileCode.getUsed()) { // 判断是否被使用
			throw new BusinessException("expired_mobile_code");
		}
		if (mobileCode.getExpiredTime().getTime()<System.currentTimeMillis()) { // 判断过期时间
			throw new BusinessException("expired_mobile_code");
		}
		if (mobileCode.getErrorTimes() >= MAX_ERROR_TIMES) { // 错误次数判断
			throw new BusinessException("expired_mobile_code");
		}
		if (mobileCode.getCode().equals(code)) { // 验证码匹配
			mobileCode.setUsed(Boolean.TRUE);
			mobileCode.setErrorTimes(mobileCode.getErrorTimes() + 1);
			mobileCodeMapper.update(mobileCode);
		}
		else { // 验证码不匹配
			mobileCode.setUpdatedTime(new Date());
			mobileCode.setErrorTimes(mobileCode.getErrorTimes() + 1);
			mobileCodeMapper.update(mobileCode);
			throw new BusinessException("error_mobile_code");
		}
	}
}
